import React, { Component } from 'react';
import 'antd/dist/reset.css';
import { Switch, Input, Select, Button, Empty, InputNumber } from 'antd';

import { JsonEditor, ActionHeader, LeftNav, KeyValueTable } from './../../components';
import { ChromeUtil } from './../../utils';

import './App.less';
import { GroupChild } from '../../configs/baseConfig';

const REQUEST_METHOD = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'];
const TAB_TYPES = ['Params', 'Headers', 'Body', 'Timeout', 'ResponseBody', 'ResponseStatus'];

export class App extends Component {

  state = {
    breadCrumb: [],
    selectedType: 'Params',
    currentNode: new GroupChild()
  }

  constructor() {
    super();
    // chrome.runtime.onMessage.addListener(({ from, to, type, data }) => {
    // });
    // ChromeUtil.sendRuntimeMsg({ type: 'poploaded', to: 'background', data: true });
  }

  componentDidMount() {
  }

  updateRequest = (selectedData) => {
    this.setState(selectedData);
  }

  collectionClick = (clickItem) => {
    this.leftNavRef.expandTree(clickItem.key);
  }

  tabClick = (tabItem) => {
    this.setState({ selectedType: tabItem });
  }


  updateNodeState = (field, value) => {
    const request = { ...this.state.currentNode.request };
    request[field] = value;
    const currentNode = { ...this.state.currentNode, request };
    this.setState({ currentNode: currentNode });
    this.leftNavRef.updateNode(currentNode);
  }

  sendData = () => {
    const reqParams = this.getRequestParams();
    new Promise((resolve) => {
      ChromeUtil.sendRuntimeMsg({ type: 'fetchData', to: 'background', data: reqParams }, resolve);
    }).then((result) => {
    }).catch(() => { });
  }

  getRequestParams = () => {
    const { body, params, method, headers } = this.state.currentNode.request;
    let url = this.state.currentNode.request.url;
    if (Array.isArray(params)) {
      const paramsArr = params.filter(item => item.isChecked && item.name).map(item => `${item.name}=${item.value}`);
      if (paramsArr.length) {
        url = [url, paramsArr.join('&')].join(url.includes('?') ? '&' : '?');
      }
    }
    const reqHeaders = {};
    if (Array.isArray(headers)) {
      headers.forEach(item => {
        if (item.isChecked && item.name) {
          reqHeaders[item.name] = item.value;
        }
      });
    }

    return {
      url,
      method,
      body: method !== 'GET' ? body : undefined,
      headers: reqHeaders
    };
  }


  render() {
    return (
      <div className="window-content">
        <ActionHeader />
        <div className='ajax-content'>
          <div className='ajax-left-nav'>
            <LeftNav ref={ref => this.leftNavRef = ref} updateRequest={this.updateRequest} />
          </div>
          <div className='ajax-right-content'>
            {
              this.state.breadCrumb.length ? (
                <>
                  <div className='header-content'>
                    <div className='bread-crumb'>
                      {
                        this.state.breadCrumb.map((item, index) => {
                          if (index === 0) {
                            return <><span onClick={() => this.collectionClick(item)}>{item.title}</span><span> / </span></>
                          }
                          return <><span>{item.title}</span></>
                        })
                      }
                    </div>
                    <Switch
                      size="small"
                      checkedChildren="开"
                      unCheckedChildren="关"
                      checked={this.state.currentNode.request.isOpen}
                      onChange={isOpen => this.updateNodeState('isOpen', isOpen)}
                    />
                  </div>


                  <div className="request-content" onClick={e => e.stopPropagation()}>
                    <Input.Group compact>
                      <Select
                        value={this.state.currentNode.request.method}
                        style={{ width: '100px' }}
                        onChange={method => this.updateNodeState('method', method)}>
                        {
                          REQUEST_METHOD.map(method => {
                            return <><Option value={method}>{method}</Option></>
                          })
                        }
                      </Select>
                      <Input
                        placeholder={'请输入url'}
                        style={{ width: 'auto', minWidth: '309px' }}
                        value={this.state.currentNode.request.url}
                        onChange={e => this.updateNodeState('url', e.target.value)}
                      />
                      <Button style={{ width: '60px' }} type="primary" disabled onClick={this.sendData}>发送</Button>
                    </Input.Group>
                  </div>

                  <div className='tabs-content'>
                    {TAB_TYPES.map(typeItem => {
                      return <>
                        <div className={`tab-item ${typeItem === this.state.selectedType ? 'selected-item' : ''}`}
                          onClick={() => this.tabClick(typeItem)}>{typeItem}</div>
                      </>
                    })}
                  </div>
                  <div className='config-conetnt'>
                    {
                      this.state.selectedType === 'Params' && (<>
                        <div>
                          <KeyValueTable dataSource={this.state.currentNode.request.params}
                            nodeKey={this.state.currentNode.key}
                            updateKeyValue={(data) => this.updateNodeState('params', data)} />
                        </div>
                      </>)
                    }
                    {
                      this.state.selectedType === 'Headers' && (<>
                        <div>
                          <KeyValueTable dataSource={this.state.currentNode.request.headers}
                            nodeKey={this.state.currentNode.key}
                            updateKeyValue={(data) => this.updateNodeState('headers', data)} />
                        </div>
                      </>)
                    }
                    {
                      this.state.selectedType === 'Body' && (<>
                        <div>
                          <JsonEditor
                            text={this.state.currentNode.request.body}
                            nodeKey={this.state.currentNode.key}
                            updateNodeState={(data) => this.updateNodeState('body', data)}
                          />
                        </div>
                      </>)
                    }
                    {
                      this.state.selectedType === 'Timeout' && (<>
                        <div className='flex-center status-content'>
                          <span className='title'>超时时间</span>
                          <InputNumber
                            style={{ width: '100px' }}
                            value={this.state.currentNode.request.timeout}
                            onChange={val => this.updateNodeState('timeout', val)}
                          /> &nbsp;ms
                        </div>
                      </>)
                    }
                    {
                      this.state.selectedType === 'ResponseBody' && (<>
                        <div>
                          <JsonEditor
                            text={this.state.currentNode.request.resBody}
                            nodeKey={this.state.currentNode.key}
                            updateNodeState={(data) => this.updateNodeState('resBody', data)}
                          />
                        </div>
                      </>)
                    }
                    {
                      this.state.selectedType === 'ResponseStatus' && (<>
                        <div className='flex-center status-content'>
                          <span className='title'>状态码</span>
                          <InputNumber
                            style={{ width: '100px' }}
                            value={this.state.currentNode.request.resStatus}
                            onChange={val => this.updateNodeState('resStatus', val)}
                          />
                        </div>
                      </>)
                    }
                  </div>
                </>
              ) : <Empty />}
          </div>
        </div>
      </div>
    );
  }
}